home *** CD-ROM | disk | FTP | other *** search
/ Fritz: All Fritz / All Fritz.zip / All Fritz / FILES / PROGNG_C / TURBOCU1.LZH / QBOUNC.C < prev    next >
Text File  |  1987-09-05  |  14KB  |  266 lines

  1. /*
  2.       THE USE OF QLIB FUNCTIONS IN CREATING BOUNCE BAR MENUS
  3.                   GARRY J. VASS  [72307,3311]
  4.  
  5.       Copyright (c), 1987, Telemacus Software Associates
  6.  
  7.  
  8.      QBOUNCE.C NOTES
  9.      ---------------
  10.  
  11.      This program demonstrates the use of QLIB to create
  12.      "bounce-bar" menus.  These menus (and their cousins,
  13.      the "pull downs") are regarded as highly intuitive/
  14.      user-friendly.  To compile this program, make a project
  15.      file that includes this program and the qlib specification.
  16.      In the interactive environment, use the <ALT-R> sequence.
  17.  
  18.      QLIB registrants are urged to employ these functions as
  19.      appropriate and issue them in compiled form.  The source
  20.      code, however, is protected by United States Copyright
  21.      Law and may not be distributed.
  22.  
  23.      Author:  Garry J. Vass  [72307,3311]
  24.  
  25.      BOUNCE BAR PROGRAMMING TIPS:
  26.      ----------------------------
  27.  
  28.      1.     Keep the menu width as narrow as possible, remember
  29.             that there are two qsnap i/o's for every keystroke.
  30.      2.     Try and stay on the conservative side with the
  31.             menu foreground/background attributes.  A lot of
  32.             folks out there live in the mono world and can only
  33.             see 7 (white) clearly.
  34.      3.     If possible, use unique first letters for your
  35.             menu choices.  Future versions of QLIB will support
  36.             the "first character selection".
  37.  
  38.      PREREQUISITES:
  39.      --------------
  40.  
  41.      1.   The TURBO C compiler, set to LARGE model.  Other MAJOR
  42.           compilers will work, but any adverse outcome is
  43.           your own problem.
  44.      2.   QLIB.LIB (Version 3 or higher) must be available
  45.           in order to link.  If you don't have QLIB, and are
  46.           unable to find it on your favorite BBS, send your
  47.           name, address, and $35 to
  48.  
  49.                Lisa T. Vass
  50.                5311 Blvd East # 3
  51.                West New York, NJ  07093
  52.  
  53.           QLIB registrants receive updates for one year mailed
  54.           automatically to the address provided with no additional
  55.           action required on your part.  A user-type documentation
  56.           package is also included by return mail.
  57.      3.   Several registrants have observed that QLIB will work
  58.           with COMPACT, HUGE, etc. models.  While these discoveries
  59.           are fun, please note that QLIB is supported in the LARGE
  60.           environment only.
  61.  
  62.  
  63. */
  64.  
  65. #define return_pressed       13          /* Variables returned by    */
  66. #define up_arrow_pressed     0x0148      /* qreadkbd().  See qfocus  */
  67. #define down_arrow_pressed   0x0150      /* screens.                 */
  68.  
  69. typedef unsigned char qstring[79];       /*                          */
  70. typedef struct        qmenustructure     /*  Bounce bar menu struct  */
  71.           {                              /*                          */
  72.           int screen_x;                  /*  Upper left column       */
  73.           int screen_y;                  /*  Upper row               */
  74.           int menu_width;                /*  Menu width in columns   */
  75.           int foreground;                /*  Foreground color        */
  76.           int background;                /*  Background color        */
  77.           int option_count;              /*  Total number of options */
  78.           int prior_choice;              /*  Choice last call        */
  79.           qstring title;                 /*  Menu title              */
  80.           qstring option_text[10];       /*  Option list to max of   */
  81.           } qmenurecord;                 /*  ten.                    */
  82.                                          /*                          */
  83.                                          /*                          */
  84.                                          /*                          */
  85.  
  86.  
  87. qmenurecord mainmenu =                   /* Declare and initialize in*/
  88.      {                                   /* one step.                */
  89.      28,                                 /* column 28                */
  90.      7,                                  /* row 7                    */
  91.      20,                                 /* 20 columns wide          */
  92.      15,                                 /* bright white foreground  */
  93.      0,                                  /* black background         */
  94.      5,                                  /* five options (from zero) */
  95.      0,                                  /* Never called before      */
  96.      "[ MAIN MENU ]",                    /* Title                    */
  97.      "Do This",                          /* Option 0                 */
  98.      "Do That",                          /* Option 1                 */
  99.      "Do Something else",                /* Option 2                 */
  100.      "**Do Wah Diddy**",                 /* Option 3                 */
  101.      "Do Bee Do Bee Do",                 /* Option 4                 */
  102.      "Leave the demo"                    /* Option 5                 */
  103.      };                                  /*                          */
  104.  
  105. qmenurecord secondary =                  /* Declare and initialize   */
  106.      {                                   /* a second-level menu to   */
  107.      28,                                 /* demonstrate the threading*/
  108.      11,                                 /* possibilities.           */
  109.      30,                                 /*                          */
  110.      7,                                  /* Please remember that the */
  111.      0,                                  /* options start at ZERO.   */
  112.      4,                                  /*                          */
  113.      0,                                  /* The last option should   */
  114.      "[ SECONDARY MENU ]",               /* always be the exit       */
  115.      "FOXTROT",                          /* condition.               */
  116.      "TANGO",                            /*                          */
  117.      "WALTZ",                            /*                          */
  118.      "CHARLESTON",                       /*                          */
  119.      "STOP DANCING",                     /*                          */
  120.      };                                  /*                          */
  121.  
  122.  
  123. void qpad(qstring st, int n)             /* No frills padding, see   */
  124. {                                        /* QLIB 4 for fast function.*/
  125. qstring temp = "";                       /*                          */
  126. qstring blank = " ";                     /*                          */
  127.      while(strlen(st) + strlen(temp)  < n)
  128.           {
  129.           strcat(st, blank);
  130.           strcat(temp, blank);
  131.           }
  132.      strcat(temp, st);
  133.      strcpy(st, temp);
  134.      if (strlen(st) % 2 == n % 2) strcat(st, blank);
  135. }
  136. int qbounce_bar(qmenurecord *m)     /* Returns an integer       */
  137. {                                   /*                          */
  138. unsigned char normal;               /* Normal/reverse get calcu-*/
  139. unsigned char reverse;              /* lated for convenience.   */
  140. int  current_option = 0;            /*                          */
  141. unsigned int  keyvar;               /* See QLIB documentation   */
  142.                                     /*                          */
  143.                                     /*                          */
  144.      qgotoxy(0, 25);                /*                          */
  145.      normal  = ((m ->background<<4) +
  146.                     m ->foreground) & 127;
  147.      reverse = ((m ->foreground<<4) +
  148.                     m ->background) & 127;
  149.      qdrawbox     (                                /* Draw a box to hold the   */
  150.                m ->screen_x - 1,                   /* menu.                    */
  151.                m ->screen_y - 2,                   /*                          */
  152.                m ->screen_x + m ->menu_width + 1,  /*                          */
  153.                m ->screen_y + m ->option_count + 2,/*                          */
  154.                m ->title, "",                      /*                          */
  155.                reverse,                            /*                          */
  156.                normal,                             /*                          */
  157.                normal);                            /*                          */
  158.      for (current_option=0;                        /* Pad the options to center*/
  159.           current_option<=m ->option_count;        /* within the menu width    */
  160.           ++current_option)                        /*                          */
  161.           {                                        /*                          */
  162.           qpad(m ->option_text[current_option],    /*                          */
  163.                m ->menu_width);                    /*                          */
  164.           qsnap                                    /* Display the options      */
  165.                (                                   /*                          */
  166.                m ->option_text[current_option],    /*                          */
  167.                m ->screen_x,                       /*                          */
  168.                m ->screen_y + current_option,      /*                          */
  169.                normal                              /*                          */
  170.                );                                  /*                          */
  171.           }                                        /*                          */
  172.      keyvar = 0;                                   /*                          */
  173.      current_option = m ->prior_choice;            /* Set an initial value for */
  174.      while(keyvar != return_pressed)               /* choice.                  */
  175.           {                                        /*                          */
  176.           qsnap                                    /* Highlight the new option */
  177.                (                                   /*                          */
  178.                m ->option_text[current_option],    /*                          */
  179.                m ->screen_x,                       /*                          */
  180.                m ->screen_y + current_option,      /*                          */
  181.                reverse                             /*                          */
  182.                );                                  /*                          */
  183.           qturn_num_lock_off();                    /*                          */
  184.           keyvar = qreadkbd();                     /* Get the arrow key        */
  185.           qsnap                                    /* Unhighlight the old      */
  186.                (                                   /* option                   */
  187.                m ->option_text[current_option],    /*                          */
  188.                m ->screen_x,                       /*                          */
  189.                m ->screen_y + current_option,      /* Inc/dec according to the */
  190.                normal                              /* keystroke, and wrap      */
  191.                );                                  /* around if upper/lower    */
  192.                                                    /* limits are reached.      */
  193.                                                    /*                          */
  194.                                                    /*                          */
  195.                                                    /*                          */
  196.           if (keyvar == up_arrow_pressed  )      --current_option;
  197.           if (keyvar == down_arrow_pressed)      ++current_option;
  198.           if (current_option > m ->option_count) current_option = 0;
  199.           if (current_option < 0          )       current_option = m ->option_count;
  200.           }                                        /* When a choice is made,   */
  201.      m -> prior_choice = current_option;           /* store it for next time   */
  202.      return(current_option);                       /* and return it as the     */
  203. }                                                  /* function value.          */
  204. main()                                             /*                          */
  205.  
  206. /* Main code begins here    */
  207. /*                          */
  208. /*                          */
  209. {
  210. int mainkey             = 0;
  211. qstring mainstring      = "You have elected to ";
  212. qstring secondarystring = "You have asked me to ";
  213. qstring hitanykey       = "hit any key to continue";
  214. int user_choice         = 0;
  215.  
  216.      while (user_choice != mainmenu.option_count)
  217.           {
  218.           qclrscr(15);
  219.           user_choice = qbounce_bar(&mainmenu);
  220.           qclrscr(15);
  221.           qcenter_line(mainstring,                        12, 15);
  222.           qcenter_line(mainmenu.option_text[user_choice], 14, 15);
  223.           qcenter_line(hitanykey,                         16, 15);
  224.           mainkey = qreadkbd();
  225.  
  226. /*                          */
  227. /*                          */
  228. /* This particular example  */
  229. /* will jump to a secondary */
  230. /* menu whenever option 3   */
  231. /* is selected.  The logic  */
  232. /* to implement threading   */
  233. /* follows.  Upon return,   */
  234. /* the default main menu    */
  235. /* option will be preserved.*/
  236. /* Using this structure,    */
  237. /* menus can be nested until*/
  238. /* the cows come home.      */
  239. /*                          */
  240. /*                          */
  241.  
  242.           if (user_choice == 3)
  243.                {
  244.                user_choice = 0;
  245.                while (user_choice != secondary.option_count)
  246.                     {
  247.                     qclrscr(15);
  248.                     user_choice = qbounce_bar(&secondary);
  249.                     qclrscr(15);
  250.                     qcenter_line(secondarystring,                    12, 15);
  251.                     qcenter_line(secondary.option_text[user_choice], 14, 15);
  252.                     qcenter_line(hitanykey,                          16, 15);
  253.                     mainkey = qreadkbd();
  254.                     }
  255.                }
  256.           }
  257. /* For an interesting       */
  258. /* diversion, simply delete */
  259. /* this next line and check */
  260. /* the error messages.      */
  261.      qgotoxy(mainkey % 79, mainkey % 24);
  262. }
  263.  
  264.  
  265.          m ->screen_x,                       /*                          */
  266.                m ->screen_y + current_optio